package com.yth.extension;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.core.env.PropertySource;

import java.util.Properties;

/**
 * 在读取完BeanDefinition后，示例话Bean之前
 *
 * <li>注意：<code>BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor</code></li>
 * <li>如果不需要注册自己的beanDefinition，可以只实现BeanFactoryPostProcessor接口</li>
 * <p></p>
 * <li>动态注册自己的beanDefinition，加载classpath之外的bean</li>
 * <li>修改已经注册的beanDefinition的元信息</li>
 *
 * @author yutianhong
 * @version 1.0
 * @since 2023/08/29 14:18:20
 */
@Slf4j
public class TestBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, Ordered, EnvironmentAware {
    private static final String MY_TEST_PROPERTY_SOURCE_NAME = "myTestPropertySource";


    private ConfigurableEnvironment environment;

    @Override
    public void setEnvironment(Environment environment) {
        log.info("[EnvironmentAware::setEnvironment]");
        this.environment = (ConfigurableEnvironment) environment;
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        // 在此注册beanDefinition
        log.info("[BeanDefinitionRegistryPostProcessor::postProcessBeanDefinitionRegistry]");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        // 在此修改已经注册的beanDefinition的元信息
        log.info("[BeanFactoryPostProcessor::postProcessBeanFactory]");
        Properties newProperties = new Properties();
        String propertyKey = "test-properties-source-config";
        String modifiedValue = "modified-" + environment.getProperty(propertyKey);
        newProperties.put(propertyKey, modifiedValue);
        PropertySource<?> propertySource = new PropertiesPropertySource(MY_TEST_PROPERTY_SOURCE_NAME, newProperties);
        environment.getPropertySources().addFirst(propertySource);
    }

    @Override
    public int getOrder() {
        log.info("[BeanFactoryPostProcessor::getOrder]");
        return Integer.MAX_VALUE;
    }

}
